/*

Summary:
Use to convert basic types to string.

Remark:
These basic types are supported at present: char, unsigned char,
wchar_t, short, unsigned short, int, unsigned int, long,
unsigned long, long long and unsigned long long. Be aware that
float, double and long double are not be supported yet.

For char, signed char, unsigned char and wchar_t, ToString 
converts their numeric value, not character value, to string.
For example, ToString('0') would get string "48".

The parameter radix must be in the range 2 - 36.

Version:
0.1.0

LastUpdatedDate:
2012-12-04

CreatedDate:
2012-08-15

*/


#pragma once
#include <string>
#include "CString.h"


namespace Zaf {
namespace String {
namespace __Internal {



#define __Zaf_ToString_Call_Long_N2S__(type, value, radix, size, buffer)            \
if (radix == 10) {                                                                  \
	__N2SWrapper<CharType, long>::__N2S(value, radix, size, buffer);                \
}                                                                                   \
else {                                                                              \
	__N2SWrapper<CharType, long>::__N2S((unsigned type)value, radix, size, buffer); \
}



//Declaration
template<typename CharType, typename ValueType>
struct __N2SWrapper {
	static void __N2S(ValueType value, int radix, int size, CharType* buffer);
};



//long
template<typename CharType>
struct __N2SWrapper<CharType, long> {
	static void __N2S(long value, int radix, int size, CharType* buffer) {
		LongToStr(value, buffer, size, radix);
	}
};

//unsigned long
template<typename CharType>
struct __N2SWrapper<CharType, unsigned long> {
	static void __N2S(unsigned long value, int radix, int size, CharType* buffer) {
		ULongToStr(value, buffer, size, radix);
	}
};



//long long
template<typename CharType>
struct __N2SWrapper<CharType, long long> {
	static void __N2S(long long value, int radix, int size, CharType* buffer) {
		LLongToStr(value, buffer, size, radix);
	}
};

//unsigned long long
template<typename CharType>
struct __N2SWrapper<CharType, unsigned long long> {
	static void __N2S(unsigned long long value, int radix, int size, CharType* buffer) {
		ULLongToStr(value, buffer, size, radix);
	}
};



//char
template<typename CharType>
struct __N2SWrapper<CharType, char> {
	static void __N2S(char value, int radix, int size, CharType* buffer) {
		__Zaf_ToString_Call_Long_N2S__(char, value, radix, size, buffer);
	}
};

//signed char
template<typename CharType>
struct __N2SWrapper<CharType, signed char> {
	static void __N2S(signed char value, int radix, int size, CharType* buffer) {
		__Zaf_ToString_Call_Long_N2S__(char, value, radix, size, buffer);
	}
};

//unsigned char
template<typename CharType>
struct __N2SWrapper<CharType, unsigned char> {
	static void __N2S(unsigned char value, int radix, int size, CharType* buffer) {
		__N2SWrapper<CharType, long>::__N2S(value, radix, size, buffer);
	}
};



//wchar_t
template<typename CharType>
struct __N2SWrapper<CharType, wchar_t> {
	static void __N2S(wchar_t value, int radix, int size, CharType* buffer) {
		__N2SWrapper<CharType, long>::__N2S(value, radix, size, buffer);
	}
};



//short
template<typename CharType>
struct __N2SWrapper<CharType, short> {
	static void __N2S(short value, int radix, int size, CharType* buffer) {
		__Zaf_ToString_Call_Long_N2S__(short, value, radix, size, buffer);
	}
};

//unsigned short
template<typename CharType>
struct __N2SWrapper<CharType, unsigned short> {
	static void __N2S(unsigned short value, int radix, int size, CharType* buffer) {
		__N2SWrapper<CharType, long>::__N2S(value, radix, size, buffer);
	}
};



//int
template<typename CharType>
struct __N2SWrapper<CharType, int> {
	static void __N2S(int value, int radix, int size, CharType* buffer) {
		__N2SWrapper<CharType, long>::__N2S(value, radix, size, buffer);
	}
};

//unsigned int
template<typename CharType>
struct __N2SWrapper<CharType, unsigned int> {
	static void __N2S(unsigned int value, int radix, int size, CharType* buffer) {
		__N2SWrapper<CharType, unsigned long>::__N2S(value, radix, size, buffer);
	}
};



} // __Internal



#define __Zaf_ToString_DefaultRadix__ (10)
#define __Zaf_ToString_MaxNumberDigits__ (64)



template<typename CharType, typename ValueType>
inline std::basic_string<CharType> ToString(ValueType value, int radix = __Zaf_ToString_DefaultRadix__) {

	CharType buffer[__Zaf_ToString_MaxNumberDigits__ + 1];

	__Internal::__N2SWrapper<CharType, ValueType>::__N2S(
		value, 
		radix, 
		__Zaf_ToString_MaxNumberDigits__ + 1, 
		buffer
	); 

	return buffer;
}


} 
}